SEMÁNTICA FORMAL
DE LOS LENGUAJES DE
PROGRAMACIÓN

“Ningún lenguaje consistente puede contener los medios necesarios para definir su propia semántica” (Alfred Tarski)



Modelos Semánticos Formales de los Lenguajes de Programación

La semántica es el campo que estudia el significado de los lenguajes e incluye: Un formalismo semántico ideal debe ser: no ambiguo, legible, modular, flexible y práctico.

La semántica formal de los lenguajes de programación trata de las posibles formas de representar el significado o interpretación de los lenguajes de programación, y tiene las utilidades siguientes: Los más importantes modelos semánticos formales para los lenguajes de programación son los siguientes:


Semántica denotacional

La semántica denotacional trata de formalizar los significados de las expresiones sintácticas de los lenguajes de programación mediante entidades matemáticas. Estas entidades matemáticas se denominan “denotaciones” o referentes de las expresiones sintácticas. Las denotaciones son, pues, entidades matemáticas que modelan los significados de las construcciones sintácticas del lenguaje [Strachey, 2000] [Scott & Strachey, 1971] [Stoy, 1977] [Scott, 1971].

La formalización se basa en tres etapas:
  1. Primero se definen los dominios sintácticos: tipos de identificadores, de expresiones, de sentencias, etc.

  2. En segundo lugar, se definen los dominios semánticos: conjuntos, funciones, estructuras algebraicas, etc. Hay modelos denotacionales que utilizan estructuras matemáticas más abstractas, como: espacios métricos, espacios topológicos, categorías, etc.

  3. En tercer lugar, se definen las funciones que aplican dominios sintácticos en dominios semánticos.
Las características de la semántica denotacional son: La semántica denotacional fue introducida inicialmente en 1967 por Chrisopher Strachey [2000] para formalizar la semántica del cálculo lambda. Posteriormente, Strachey y Dana Scott establecieron sus bases teóricas utilizando la teoría de dominios (Domain Theory) ideada por Scott, inspirándose precisamente en el cálculo lambda [Scott & Strachey, 1971]. El estudio de los tipos o categorías de dominios y sus propiedades es el objeto de la teoría de dominios. Los tipos de expresiones lingüísticas se interpretan como dominios.

La tendencia actual es contemplar la semántica denotacional desde el punto de vista de la teoría de modelos, y en donde la teoría de dominios es una rama de la teoría de modelos.


Semántica operacional

En la semántica operacional, la semántica de un programa se establece a través de una máquina abstracta que asocia a cada construcción sintáctica una secuencia de ejecución, es decir, describe el “cómo” se comportan los programas de manera explícita, precisa y detallada. Esta máquina abstracta debe disponer de primitivas operacionales de significado claro y preciso.

Dos programas que codifiquen (por ejemplo) la factorial de un número de manera diferente tienen distintas semánticas operacionales.

La semántica operacional también se denomina “semántica intensional” porque la semántica reside en las computaciones que se realizan a nivel interno, no visible, en la máquina abstracta.

En general, se considera que la semántica operacional complementa a la semántica denotacional, y que ambas semánticas son necesarias para una descripción completa de un lenguaje de programación. La semántica operacional para especificar el comportamiento de un programa. Y la semántica denotacional para razonar sobre los programas en términos de entidades abstractas.

El primer ejemplo de semántica operacional fue la definición de un intérprete para Lisp (escrito en el propio Lisp). Con Lisp es posible definir también la semántica operacional de cualquier lenguaje. Otros lenguajes definidos con semántica operacional son: Algol 60, PL/I y CSP.

A finales de los años 1960s apareció un lenguaje más elaborado para la definición de la semántica operacional llamada Universal Language Definer, que posteriormente se denominó VDL (Vienna Definition Language) [Wegner, 1972]. VDL se aplicó para definir la semántica del lenguaje PL/I, que fue el primer lenguaje que nació con una semántica definida, aunque no totalmente formal. Una versión posterior de VDL dió origen al VDM (Vienna Development Method), una metodología de desarrollo de software [Bjorner, 1978].


Semántica operacional estructural (Structural Operational Semantics, SOS)

Es una forma de semántica operacional ideada por Gordon Plotkin [2004] que tiene las características siguientes: La SOS se ha convertido en la forma más común para definir la semántica operacional y uno de los principales modelos semánticos formales por sus ventajas: Debido a su carácter general y a su difusión, la SOS se ha convertido en objeto de estudio por sí mismo, lo que ha conducido a diversas líneas de investigación que proponen diversos formatos de reglas y sus meta-teoremas asociados. Mediante una formalización de la SOS denominada “Transition System Specificacions” (TSS), se pueden deducir interesantes propiedades sobre la semántica operacional inducida. Las propiedades obtenidas por estos formatos de reglas abarcan desde su aplicación original a la semántica operacional hasta equivalencias en modelos de comportamiento en diversas áreas de aplicación.


Semántica axiomática

En la semántica axiomática, el significado de un lenguaje de programación se describe mediante axiomas de la lógica de predicados, es decir, como una teoría de los programas escritos en ese lenguaje en forma de axiomas, que son reglas de inferencia que caracterizan las diferentes construcciones del lenguaje. La forma general de las reglas es en donde C es una construcción sintáctica del lenguaje, P (precondición) y Q (postcondición) son aserciones (fórmulas del cálculo de predicados). Su significado es: Si se ejecuta C en un estado en el que se cumple la condición P, entonces producirá un resultado en el que se cumplirá la condición Q, que está determinada por P y C. Estas reglas establecen relaciones lógicas entre estados iniciales y finales. Hay que asociar al menos una regla para cada constructo C del lenguaje. Un ejemplo de regla es: Como en toda teoría matemática, en la semántica axiomática hay: Una fórmula puede ser verdadera o falsa. Una fórmula verdadera es un teorema. El objeto de la teoría es definir qué fórmulas son teoremas.

Las construcciones sintácticas básicas (como la sentencia de asignación) se definen como axiomas.

Las construcciones sintácticas compuestas (como While) se definen mediante teoremas derivables de los axiomas, usando reglas de inferencia para la composición de programas.

La semántica axiomática se utiliza normalmente a posteriori, es decir, una vez definido el lenguaje, se estudia su semántica axiomática. Con este formalismo se facilita la demostración de propiedades de los programas y su verificación a posteriori (una vez desarrollados).

El modelo axiomático es más abstracto que el denotacional y, sin embargo, es más práctico. Es más abstracto porque no trata realmente del significado de un programa, sino sólo lo que puede demostrarse sobre él, sus propiedades. Y es más práctico porque permite formalizar las construcciones de un lenguaje.

El ejemplo canónico de la semántica axiomática es la lógica de Hoare [1969]. De hecho, las reglas utilizan las “ternas de Hoare” (P, C, Q).

Otro enfoque axiomático se basa en considerar los programas como demostraciones a partir de un cierto conjunto de axiomas. En la correspondencia Curry-Howard, los tipos de datos son teoremas y los programas son demostraciones de los teoremas. [ver Aplicaciones  Lógica  Correspondencia Curry-Howard.]


Semántica algebraica

Es una forma de semántica axiomática basada en leyes algebraicas del álgebra abstracta para formalizar la semántica. Los axiomas son especificaciones ecuacionales de las operaciones. Se basa en identificar las diferentes clases de objetos y las diferentes operaciones que se pueden realizar sobre ellos. También se utilizan axiomas algebraicos para describir las características de dichos objetos.

La semántica algebraica permite especificar todo tipo de objetos, de bajo o alto nivel.

La metodología de la semántica algebraica se usa también para especificar tipos abstractos de datos (TADs). Es decir, las propiedades de los objetos de datos se definen mediante operaciones que acceden y manipulan los datos, sin tener en cuenta su implementación concreta.

La semántica algebraica surgió a finales de los años 1970s. Se basa en la teoría matemática del álgebra universal. Una especificación algebraica permite definir una estructura matemática de forma abstracta, junto con sus propiedades.

Existen varios lenguajes de especificación algebraica, como ASL, Larch, ACT One, Clear y OBJ. En el caso de OBJ, las sentencias son ecuaciones, las computaciones son demostraciones de teoremas, y los programas son teorías.


Semántica de acciones

En la semántica de acciones (action semantics), la semántica de un lenguaje se especifica mediante acciones, que expresan computaciones formalizadas a partir de unas acciones primitivas. Hay acciones derivadas, que son combinaciones de acciones primitivas.

La modelización de los diferentes tipos de acciones se realiza mediante facetas. Hay 5 tipos de facetas: básica, funcional, declarativa, imperativa y comunicativa. Cada faceta captura un determinado aspecto computacional.

La semántica de acciones fue propuesta por Peter Mosses [1992] con el fin de crear especificaciones semánticas legibles, modulares y prácticas.


Semántica categorial

Es una semántica que usa la teoría matemática de categorías como formalismo para especificar la semántica. La teoría de las categorías es una teoría unificadora de las estructuras matemáticas. Una aplicación de la teoría de categorías a la semántica de los lenguajes de programación ha sido realizada por Pierce [1991].


Gramáticas de atributos

Son gramáticas que extienden la gramática formal libre de contexto de un lenguaje para especificar la semántica [Knuth, 1968]. El proceso de añadir semántica a una descripción sintáctica se denomina”decoración”. La decoración se aplica a: Los atributos se clasifican en: Este modelo semántico es un marco general para especificar la semántica, más que un método completamente definido, pues está abierto a la elección de los atributos y las reglas.

Las gramáticas de atributos se aplican a gran variedad de campos, entre ellos: especificación formal (sintaxis y semántica) de los lenguajes de programación, generación automática de compiladores, definición formal de entornos de programación, programación lógica, teoría de la complejidad, representación del conocimiento, reconocimiento del lenguaje natural y reconocimiento de patrones.

Una gramática de atributos se puede considerar como una semántica denotacional en donde el lenguaje original es enriquecido con atributos o anotaciones.


MENTAL, un Modelo Semántico General de los Lenguajes de Programación

En los últimos años ha habido una enorme proliferación de modelos semánticos formales de los lenguajes de programación. Todo este panorama genera confusión, produce perplejidad y nos conduce a plantearnos: 1) en primer lugar, sobre la verdadera naturaleza de la semántica; 2) la cuestión de la posibilidad de la existencia de un modelo formal unificado y simple del que surjan todos los modelos particulares, pues se sospecha que esta diversidad es solo aparente, y que tras esta diversidad de modelos se esconde algo fundamentalmente simple.

Mientras que para la especificación de la sintaxis de un lenguaje de programación se utiliza universalmente la notación estándar BNF o BNFE (BNF extendido), para la especificación de la semántica existen diferentes modelos formales, pero ninguno de estos modelos se ha convertido en estándar, pues ninguno ha alcanzado ni popularidad ni un alto grado de utilización, porque ninguno se ha considerado completo. Se puede decir que la especificación de la semántica formal ha fracasado. Y ha fracasado por una razón muy simple: porque la semántica de un lenguaje es inexpresable desde fuera del lenguaje y desde dentro (el lenguaje no puede expresar su propia semántica).

El significado no es algo externo, representable y objetivable. El significado es algo interno (mental), subjetivo y no representable. Sin embargo, el significado se fundamenta en arquetipos comunes al mundo interno y externo, por lo que es compartido por todos los seres humanos. Lo externo nos conecta con lo interno. Esa conexión es la conciencia. El significado “no está en la cabeza” sino en otra dimensión de la realidad, en la dimensión mental y en la conciencia. El significado es un fenómeno mental, de conciencia, y los significados de las expresiones lingüísticas se corresponden con las representaciones a nivel interno.

A la semántica de un lenguaje de programación se la ha relacionado con entidades matemáticas abstractas, con lo operativo, con el álgebra, con la lógica, con la demostración, etc. La semántica está muy relacionada con el tipo, con la categoría, con lo intensivo, pues todo ente particular debe verse como una instancia de algo general o profundo. Por lo tanto, la semántica no se puede formalizar. La única forma de formalizar la semántica es ligarla a la sintaxis como manifestación de los arquetipos primarios. Entonces se produce la integración de todos los formalismos semánticos anteriores en un modelo formal universal o unificado con el que se pueden especificar todos los modelos formales particulares.

Siempre se ha considerado que la semántica de un lenguaje de programación es más difícil de formalizar que la sintaxis. En el caso de MENTAL, ambos aspectos se igualan porque van unidos. Como la semántica no se puede expresar, en general para especificar la semántica de un lenguaje de programación, es necesario usar descripciones informales en lenguaje natural y ejemplos como manifestaciones superficiales de la semántica. Esto también se hace en MENTAL, pero como las primitivas semánticas son simples y la sintaxis también, las descripciones se reducen al máximo.

En MENTAL, la epistemología y la ontología van unidas. Por eso es el lenguaje de la conciencia.

MENTAL es un modelo semántico formal unificado que, por su alto nivel de abstracción, integra e interrelaciona todos los modelos semánticos formales anteriormente mencionados. Ocurre lo mismo que con los paradigmas de programación, pues MENTAL ofrece un paradigma universal que permite especificar todos los paradigmas particulares. En definitiva, por su supremo nivel de abstracción, MENTAL proporciona una semántica natural y universal que permite formalizar todos los modelos semánticos descritos. MENTAL es la semántica formal de todos los lenguajes de programación y el formalismo semántico de todo programa. El modelo de MENTAL trasciende la informática y la matemática. Es un modelo semántico universal en el que sintaxis y semántica van unidas, que es una característica de la conciencia.



Adenda

Teoría de dominios

La teoría de dominios es una rama de la matemática que estudia clases especiales de conjuntos parcialmente ordenados (partially ordered sets, posets) denominados “dominios”.

Un poset es un conjunto en el que se ha definido una relación de orden parcial (≤) binaria entre sus elementos que cumple las propiedades: A finales de los años 1960s, Dana Scott −un alumno de Church− formalizó, con la ayuda del cálculo lambda, unas estructuras matemáticas que denominó “dominios”, que servían para representar tipos funcionales, en lugar de los tipos de los conjuntos tradicionales [Abramsky & Jung, 1994]. Su motivación principal fue formalizar la semántica del cálculo lambda mediante la semántica denotacional.
Bibliografía